package com.ayf.payment.game.api.controller;

import com.ayf.payment.game.api.dto.MerchantDTO;
import com.ayf.payment.game.api.dto.ReissueAllTaskDTO;
import com.ayf.payment.game.api.dto.ReissueRecordDTO;
import com.ayf.payment.game.api.dto.ReissueRecordVO;
import com.ayf.payment.game.api.dto.criteria.ReissueRecordCriteria;
import com.ayf.payment.game.api.dto.criteria.ReissueRecordSelectCriteria;
import com.ayf.payment.game.api.entity.Merchant;
import com.ayf.payment.game.api.exception.BusinessException;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.service.ReissueRecordService;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.utils.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.exception.GetLockFailedException;
import com.swwx.charm.zookeeper.exception.ReleaseLockFailedException;
import com.swwx.charm.zookeeper.lock.DistributedLock;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 补发功能
 *
 * @author wwl
 * @date 2019/12/6 15:13
 */
@RequestMapping("/v/reissueRecord")
@RestController
public class ReissueRecordController {

    @Autowired
    private ReissueRecordService reissueRecordService;

    @Autowired
    private MerchantService merchantService;

    @Autowired
    protected DistributedLock distributedLock;

    /**
     * 补发数据询
     * @param merchantDTO
     * @param selectCriteria
     * @return
     */
    @PostMapping("/selectAll")
    public CommonResult<ReissueRecordVO> selectPage(MerchantDTO merchantDTO, @RequestBody ReissueRecordSelectCriteria selectCriteria) {
        if ("SON".equals(merchantDTO.getLoginType())) {
            selectCriteria.setLoginId(merchantDTO.getLoginId());
        }
        selectCriteria.setMerchantId(merchantDTO.getId());
        PageHelper.startPage(selectCriteria.getPageNum(), selectCriteria.getPageSize());
        List<ReissueRecordDTO> reissueRecordDTO = reissueRecordService.selectByPage(selectCriteria);
        PageInfo<ReissueRecordDTO> pageInfo=new PageInfo<>(reissueRecordDTO);
        ReissueRecordVO vo = reissueRecordService.selectTotalAmountByPage(selectCriteria);
        if (vo == null) {
            vo = new ReissueRecordVO();
            vo.setTotalAmount(BigDecimal.ZERO);
            vo.setSuccessTotalAmount(BigDecimal.ZERO);
            vo.setFailTotalAmount(BigDecimal.ZERO);
        }
        if (!CollectionUtils.isEmpty(pageInfo.getList())) {
            vo.setList(pageInfo.getList());
        }
        vo.setPageNum(pageInfo.getPageNum());
        vo.setPageSize(pageInfo.getPageSize());
        vo.setTotal(pageInfo.getTotal());

        // 查询昨日此时补发记录汇总信息
        Date yesterdayTime = DateUtils.getDayTimeBeforeDay(1);
        String yesterdayDateStr = DateUtils.dateToString(yesterdayTime,DateUtils.formatPattern);
        String startTime = "00:00:00";
        String endTime = "23:59:59";
        if(StringUtils.isNotEmpty(selectCriteria.getStartTime())){
            startTime = selectCriteria.getStartTime().substring(selectCriteria.getStartTime().indexOf(" ")+1);
        }
        if(StringUtils.isNotEmpty(selectCriteria.getEndTime())){
            endTime = selectCriteria.getEndTime().substring(selectCriteria.getEndTime().indexOf(" ")+1);
        }
        selectCriteria.setStartTime(yesterdayDateStr.concat(" ").concat(startTime));
        selectCriteria.setEndTime(yesterdayDateStr.concat(" ").concat(endTime));
        ReissueRecordVO yesterdayReissueSummary = reissueRecordService.selectTotalAmountByPage(selectCriteria);
        if (Objects.nonNull(yesterdayReissueSummary)){
            vo.setYesterdayTotalAmount(yesterdayReissueSummary.getTotalAmount());
            vo.setYesterdaySuccessTotalAmount(yesterdayReissueSummary.getSuccessTotalAmount());
            vo.setYesterdayFailTotalAmount(yesterdayReissueSummary.getFailTotalAmount());
        } else {
            vo.setYesterdayTotalAmount(BigDecimal.ZERO);
            vo.setYesterdaySuccessTotalAmount(BigDecimal.ZERO);
            vo.setYesterdayFailTotalAmount(BigDecimal.ZERO);
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, CommonConstants.OPERATION_SUCCESS, vo);
    }

    /**
     * 微信端--补发数据查询
     * @param request
     * @param signStr
     * @param selectCriteria
     * @return
     */
    @PostMapping("/wxSelectAll")
    public CommonResult<PageInfo> wxSelectPage(HttpServletRequest request, @RequestHeader("signStr") String signStr,
                                               @RequestBody ReissueRecordSelectCriteria selectCriteria) {
        String str = "";
        str += selectCriteria.getMerchantId();
        if (StringUtils.isNotEmpty(selectCriteria.getStartTime())) {
            str += selectCriteria.getStartTime();
        }

        if (StringUtils.isNotEmpty(selectCriteria.getEndTime())) {
            str += selectCriteria.getEndTime();
        }
        if (StringUtils.isNotEmpty(selectCriteria.getRechargeNumber())) {
            str += selectCriteria.getRechargeNumber();
        }
        if (StringUtils.isNotEmpty(selectCriteria.getPartitionId())) {
            str += selectCriteria.getPartitionId();
        }
        if (StringUtils.isNotEmpty(selectCriteria.getReissueType())) {
            str += selectCriteria.getReissueType();
        }
        if (selectCriteria.getPageSize() != 0) {
            str += selectCriteria.getPageSize();
        }
        if (selectCriteria.getPageNum() != 0) {
            str += selectCriteria.getPageNum();
        }
        String sign = MD5Util.sign(str, null);
        if (!StringUtils.equals(sign, signStr)) {
            LogPortal.error("WX_SELECT_REISSUE_RECORD_FAIL >>> 微信公众号端补发数据查询-验签失败: 商户号[{}],请求URL[{}],签名[{}],data[{}]",
                    selectCriteria.getMerchantId(), request.getRequestURL(), signStr, selectCriteria.toString());
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "非法请求", null);
        }
        //验签成功，开始补发数据查询
        PageHelper.startPage(selectCriteria.getPageNum(), selectCriteria.getPageSize());
        List<ReissueRecordDTO> reissueRecordDTO = reissueRecordService.selectByPage(selectCriteria);
        PageInfo pageInfo = new PageInfo(reissueRecordDTO);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, CommonConstants.OPERATION_SUCCESS, pageInfo);
    }

    /**
     * 保存整区补发数据
     * @param merchantDTO
     * @param entity
     * @return
     */
    @PostMapping("/saveAuto")
    public CommonResult<Map> saveEntity(MerchantDTO merchantDTO, @RequestBody ReissueAllTaskDTO entity, HttpServletRequest request){
        String operateIp= IPUtils.getIp(request);
        entity.setMerchantId(merchantDTO.getId());
        entity.setOperatorId(merchantDTO.getLoginId());
        entity.setOperateIp(operateIp);
        Map map = null;
        String REISSUE_WHOLE_UNIQ_PARTITION = "REISSUE_WHOLE_UNIQ_PARTITION".concat(entity.getPartitionId());
        boolean lock = false;
        String traceId = SnowFlakeUtils.getTraceId();
        String lockName = REISSUE_WHOLE_UNIQ_PARTITION.concat(System.getenv("XY_GAME_PAY_LOCK_FLAG"));
        try {
            if (lock = distributedLock.getLock(lockName)) {
                map=reissueRecordService.saveAuto(entity);
            } else {
                return new CommonResult<>(CommonConstants.RETURN_ERROR, "分区ID["+entity.getPartitionId()+"]的整区补发正在处理中，请不要重复操作",null);
            }
        }catch (GetLockFailedException e) {
            LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", traceId, lockName);
            LogPortal.error("{} >>> {} 获取lock失败", e, traceId, lockName);
        }  finally {
            if (lock) {
                try {
                    distributedLock.releaseLock(lockName);
                } catch (ReleaseLockFailedException e) {
                    LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}", traceId, lockName);
                    LogPortal.error("{} >>> {} 释放失败", e, traceId, lockName);
                }
            }
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功下发补发任务", map);
    }

    /**
     * 手动充值
     *
     * @param manualCriteria
     * @return
     */
    @PostMapping("/manual")
    public CommonResult<T> manualTopUp(HttpServletRequest request, MerchantDTO merchantDTO, @RequestBody ReissueRecordCriteria manualCriteria)  {
        manualCriteria.setOperateIp(IPUtils.getIp(request));
        manualCriteria.setMerchantId(merchantDTO.getId());
        manualCriteria.setOperatorId(merchantDTO.getLoginId());
        String reissueRecordId = reissueRecordService.manualTopUp(manualCriteria);
        if (StringUtils.isEmpty(reissueRecordId)) {
            throw new BusinessException("保存错误");
        }
        return reissueRecordService.rechargeGetWay(merchantDTO.getId(), reissueRecordId);
    }

    /**
     * 手动充值赠送明细
     * @param merchantDTO
     * @param manualCriteria
     * @return
     */
    @PostMapping("/manualGiveDetail")
    public CommonResult<?> manualGiveDetail(MerchantDTO merchantDTO, @RequestBody ReissueRecordCriteria manualCriteria)  {
        manualCriteria.setMerchantId(merchantDTO.getId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "手动充值赠送明细",reissueRecordService.manualGiveDetail(manualCriteria));
    }

    /**
     * 微信公众号端手动充值
     *
     * @param request
     * @param manualCriteria
     * @return
     */
    @PostMapping("/wxManual")
    public CommonResult<T> wxManualTopUp(HttpServletRequest request,
                                         @RequestBody ReissueRecordCriteria manualCriteria, @RequestHeader("signStr") String signStr) {
        String str = "";
        str += manualCriteria.getMerchantId();
        str += manualCriteria.getRechargeNumber();
        str += manualCriteria.getRechargeAmount();
        str += manualCriteria.getPartitionId();
        str += manualCriteria.getChannelName();
        str += manualCriteria.getManualType();
        Merchant merchant = merchantService.find(manualCriteria.getMerchantId());
        String sign = MD5Util.sign(str, null);
        if (!StringUtils.equals(sign, signStr)) {
            LogPortal.error("WX_MANUAL_VERIFY_FAIL >>> 微信公众号端手动充值-验签失败: 商户号[{}],请求URL[{}],签名[{}],data[{}]",
                    manualCriteria.getMerchantId(),request.getRequestURL(), signStr,manualCriteria.toString());
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "非法请求", null);
        }
        //验签成功，开始手动充值
        manualCriteria.setOperateIp(IPUtils.getIp(request));
        String reissueRecordId = reissueRecordService.manualTopUp(manualCriteria);
        if (StringUtils.isEmpty(reissueRecordId)) {
            throw new BusinessException("保存错误");
        }
        return reissueRecordService.rechargeGetWay(manualCriteria.getMerchantId(), reissueRecordId);

    }

    /**
     * 微信公众号保存整区补发数据
     *
     * @param entity
     * @return
     */
    @PostMapping("/wxSaveAuto")
    public CommonResult<String> wxSaveEntity(@RequestBody ReissueAllTaskDTO entity,
                                             HttpServletRequest request, @RequestHeader("signStr") String signStr) {
        String str = "";
        str+=entity.getMerchantId();
        if (StringUtils.isNotEmpty(entity.getAutoType())) {
            str += entity.getAutoType();
        }
        str += entity.getPartitionId();
        str += entity.getPartitionName();
        str += entity.getIsAutoReissue();
        if (StringUtils.isNotEmpty(entity.getAutoReissueTime())) {
            str += entity.getAutoReissueTime();
        }
        str += entity.getReissueStartTime();
        str += entity.getReissueEndTime();
        str += entity.getIsCleanData();
        if (entity.getReissueQuota() != null) {
            str += entity.getReissueQuota();
        }
        String sign = MD5Util.sign(str, null);
        if (!StringUtils.equals(sign, signStr)) {
            LogPortal.error("WX_SAVE_AUTO_VERIFY_FAIL >>> 微信公众号保存整区补发数据-验签失败: 请求URL[{}],商户号[{}],签名[{}],data[{}]",
                    request.getRequestURL(),
                    entity.getMerchantId(), signStr,entity.toString());
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "非法请求", null);
        }
        //验签成功，开始整区补发
        entity.setOperateIp(IPUtils.getIp(request));
        reissueRecordService.saveAuto(entity);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功下发补发任务", "");
    }

    /**
     * 查询出手动充值的记录
     *
     * @param merchantDTO
     * @param selectCriteria
     * @return
     */
    @PostMapping("/selectAllManual")
    public CommonResult<PageInfo> selectAllManual(MerchantDTO merchantDTO, @RequestBody ReissueRecordSelectCriteria selectCriteria){
        if (merchantDTO == null) {
            throw new ParameterException("未登录");
        }
        selectCriteria.setMerchantId(merchantDTO.getId());
        PageInfo pageInfo = reissueRecordService.selectAllManual(selectCriteria);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, CommonConstants.OPERATION_SUCCESS, pageInfo);
    }
}
